#include "POSIX_MsgServer.hpp"
#include <stdexcept>
#include <cstring>
#include <iostream>

POSIX_MsgServer::POSIX_MsgServer(const char* msgname)
  : threadID(pthread_self())
{
  id=mq_open(msgname,O_CREAT | O_RDWR,S_IRUSR | S_IWUSR,nullptr);
  if(id==-1)
    throw std::runtime_error("无法打开posix消息队列");
  struct mq_attr attr;
  mq_getattr(id,&attr);
  receiveBuf=new char[attr.mq_msgsize];
  bufsize=attr.mq_msgsize;
}

POSIX_MsgServer::~POSIX_MsgServer()
{
  if(pthread_equal(threadID,pthread_self())==0)
    pthread_cancel(threadID);
  if(receiveThread.joinable())
    receiveThread.join();
  delete [] receiveBuf;
}

void POSIX_MsgServer::BootReceive(std::function<void(std::string && recData)> func)
{
  funcReceiveCallback=func;
  receiveThread=std::thread([this](){
    threadID=pthread_self();
    while(true)
    {
      std::memset(receiveBuf,0x0,bufsize);
      ssize_t recSize=mq_receive(id,receiveBuf,bufsize,nullptr);
      if(recSize==-1)
      {
        std::cout<<"[ERROR] 无法获取POSIX消息队列数据"<<std::endl;
        continue;
      }
      funcReceiveCallback(std::string(receiveBuf,recSize));
    }
  });
}

void POSIX_MsgServer::SendData(const std::string & sendData)
{
  if(mq_send(id,sendData.data(),sendData.size(),0)==-1)
    throw std::runtime_error("无法发送POSIX消息");
}

